package com.lib.common.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ProgressBar;

import com.lib.common.R;

public class MyCircleSeekBar extends View {

	static final int DEFAULT_RADIUS = 90;

	private static final int EDGE_MARGIN = 5;

	private static final float STROKE_WIDTH = 5;

	private Rect rect = new Rect();

	private Paint mPaint;

	private RectF mOutRectF;

	private RectF mInnerRectF;

	private final int mMax;

	private float mSweepAngle;

	private CharSequence mText;

	private int mRingProgressColor;

	private int mRingCompletedColor;

	private OnProgressChangeListener mOnProgressChangeListener;

	/**
	 * A callback that notifies clients when the progress level has been
	 * changed. This includes changes that were initiated by the user through a
	 * touch gesture or arrow key/trackball as well as changes that were initiated
	 * programmatically.
	 */
	public interface OnProgressChangeListener {

		/**
		 * 进度开始
		 *
		 * @param myCircleSeekBar
		 * 	控件对象
		 */
		void onProgressStarted(MyCircleSeekBar myCircleSeekBar);

		/**
		 * Notification that the progress level has changed. Clients can use the fromUser parameter
		 * to distinguish user-initiated changes from those that occurred programmatically.
		 *
		 * @param myCircleSeekBar
		 * 	The SeekBar whose progress has changed
		 * @param progress
		 * 	The current progress level. This will be in the range 0..max where max
		 * 	was set by {@link ProgressBar#setMax(int)}. (The default value for max is 100.)
		 */

		void onProgressChanged(MyCircleSeekBar myCircleSeekBar, float progress);

		/**
		 * 进度完成
		 *
		 * @param myCircleSeekBar
		 * 	控件对象
		 */
		void onProgressCompleted(MyCircleSeekBar myCircleSeekBar);

	}

	public void setOnProgressChangeListener(OnProgressChangeListener l) {

		mOnProgressChangeListener = l;
	}

	public MyCircleSeekBar(Context context) {

		this(context, null);
	}

	public MyCircleSeekBar(Context context, AttributeSet attrs) {

		this(context, attrs, 0);
	}

	public MyCircleSeekBar(Context context, AttributeSet attrs, int defStyle) {

		super(context, attrs, defStyle);

		mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		mPaint.setAntiAlias(true);
		mPaint.setStrokeWidth(STROKE_WIDTH);

		TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyCircleSeekBar);
		mRingProgressColor = ta.getColor(R.styleable.MyCircleSeekBar_progressColor, Color.RED);
		mRingCompletedColor = ta.getColor(R.styleable.MyCircleSeekBar_completedColor, Color.GREEN);
		mMax = ta.getInt(R.styleable.MyCircleSeekBar_max, 100);
		mText = ta.getString(R.styleable.MyCircleSeekBar_text_tips);
		ta.recycle();

		if (mText == null) {
			mText = "0%";
		}
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

		int widthMode = MeasureSpec.getMode(widthMeasureSpec);
		int heightMode = MeasureSpec.getMode(heightMeasureSpec);
		int widthSize = MeasureSpec.getSize(widthMeasureSpec);
		int heightSize = MeasureSpec.getSize(heightMeasureSpec);

		int radius;
		if (widthMode == MeasureSpec.AT_MOST || heightMode == MeasureSpec.AT_MOST) {
			radius = Math.min(Math.min(widthSize, heightSize), DEFAULT_RADIUS);
		} else if (widthMode == MeasureSpec.EXACTLY && heightMode == MeasureSpec.EXACTLY) {
			radius = Math.min(widthSize, heightSize);
		} else {
			radius = DEFAULT_RADIUS;
		}

		if (mOutRectF == null) {
			mOutRectF = new RectF(0, 0, radius, radius);
			mPaint.setTextSize(radius / 3);
		}
		if (mInnerRectF == null) {
			mInnerRectF = new RectF(EDGE_MARGIN, EDGE_MARGIN, radius - EDGE_MARGIN, radius -
				EDGE_MARGIN);
		}
		setMeasuredDimension(radius, radius);
	}

	@Override
	protected void onDraw(Canvas canvas) {

		mPaint.getTextBounds(mText.toString(), 0, mText.length(), rect);

		if (mSweepAngle != mMax) {
			mPaint.setColor(mRingProgressColor);
		} else {
			mPaint.setColor(mRingCompletedColor);
		}
		canvas.drawArc(mOutRectF, -90, mSweepAngle / mMax * 360, true, mPaint);

		mPaint.setColor(Color.GRAY);
		canvas.drawArc(mInnerRectF, 0, 360, true, mPaint);
		if (mSweepAngle != mMax) {
			mPaint.setColor(mRingProgressColor);
		} else {
			mPaint.setColor(mRingCompletedColor);
		}
		int x = (int) (mOutRectF.width() / 2 - rect.width() / 2);
		int y = (int) (mOutRectF.height() / 2 + rect.height() / 2 - rect.bottom);

		canvas.drawText(mText.toString(), x, y, mPaint);
		// canvas.drawLine(getMeasuredWidth() / 2, 0, getMeasuredWidth() / 2, getMeasuredHeight(), mPaint);
		// canvas.drawLine(0, getMeasuredHeight() / 2, getMeasuredWidth(), getMeasuredHeight() / 2, mPaint);
	}

	public void setProgress(int sweepAngle) {

		setProgress(sweepAngle, false);
	}

	public synchronized void setProgress(int sweepAngle, boolean changeText) {

		mSweepAngle = Math.abs(sweepAngle);
		if (sweepAngle == 0) {
			if (changeText) {
				mText = "0%";
			}
			if (mOnProgressChangeListener != null) {
				mOnProgressChangeListener.onProgressStarted(this);
			}
		} else if (sweepAngle >= mMax) {
			mSweepAngle = mMax;
			if (changeText) {
				mText = "100%";
			}
			if (mOnProgressChangeListener != null) {
				mOnProgressChangeListener.onProgressCompleted(this);
			}
		} else {
			if (changeText) {
				mText = ((int) ((mSweepAngle / mMax) * 1000)) / 10.0 + "%";
			}
			if (mOnProgressChangeListener != null)
				mOnProgressChangeListener.onProgressChanged(this, mSweepAngle);
		}
		invalidate();
	}

	public void setText(CharSequence text) {

		mText = text;
		invalidate();
	}
}